"""
工单路由
提供工单系统的RESTful API接口
"""

from typing import Optional, List
import uuid
from fastapi import APIRouter, Depends, HTTPException, status, Query
from fastapi import status as http_status
from sqlalchemy.orm import Session

from src.config.database import get_db
from src.models.ticket import (
    Ticket, TicketReply, TicketCreate, TicketUpdate, TicketReplyCreate,
    TicketResponse, TicketReplyResponse, TicketStats, TicketFilter
)
from src.models.user import User
from src.services.ticket_service import TicketService
from src.services.auth_service import (
    get_current_active_user_dep, require_agent_or_admin, require_admin
)
from src.utils.logging import get_logger

logger = get_logger(__name__)


router = APIRouter(prefix="/tickets", tags=["tickets"])


@router.post("", response_model=None)
async def create_ticket(
    ticket_data: TicketCreate,
    current_user: User = Depends(get_current_active_user_dep),
    db: Session = Depends(get_db)
) -> TicketResponse:
    """创建新工单"""
    try:
        ticket = TicketService.create_ticket(db, ticket_data, current_user)
        return TicketResponse.from_orm(ticket)
    except Exception as e:
        logger.error(f"创建工单失败: {e}")
        raise HTTPException(
            status_code=http_status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="创建工单失败"
        )


@router.get("", response_model=List[TicketResponse])
async def get_tickets(
    status: Optional[List[str]] = Query(None),
    priority: Optional[List[str]] = Query(None),
    category: Optional[List[str]] = Query(None),
    assigned_to: Optional[uuid.UUID] = Query(None),
    created_by: Optional[uuid.UUID] = Query(None),
    tags: Optional[List[str]] = Query(None),
    created_after: Optional[str] = Query(None),
    created_before: Optional[str] = Query(None),
    search: Optional[str] = Query(None),
    skip: int = Query(0, ge=0),
    limit: int = Query(100, ge=1, le=1000),
    current_user: User = Depends(get_current_active_user_dep),
    db: Session = Depends(get_db)
) -> List[TicketResponse]:
    """获取工单列表"""
    try:
        # 构建筛选条件
        # 将字符串列表转换为对应的枚举类型列表
        status_filter = None
        if status:
            status_filter = [TicketStatus(s) for s in status]
            
        priority_filter = None
        if priority:
            priority_filter = [TicketPriority(p) for p in priority]
            
        category_filter = None
        if category:
            category_filter = [TicketCategory(c) for c in category]
            
        filters = TicketFilter(
            status=status_filter,
            priority=priority_filter,
            category=category_filter,
            assigned_to=assigned_to,
            created_by=created_by,
            tags=tags,
            created_after=created_after,
            created_before=created_before,
            search=search
        )
        
        tickets = TicketService.get_tickets(db, current_user, filters, skip, limit)
        ticket_responses = []
        for ticket in tickets:
            # 手动处理User对象到字典的转换
            created_by_dict = None
            if ticket.created_by:
                created_by_dict = {
                    "id": ticket.created_by.id,
                    "username": ticket.created_by.username,
                    "email": ticket.created_by.email,
                    "display_name": ticket.created_by.display_name,
                    "role": ticket.created_by.role,
                    "status": ticket.created_by.status
                }
            
            assigned_to_dict = None
            if ticket.assigned_to:
                assigned_to_dict = {
                    "id": ticket.assigned_to.id,
                    "username": ticket.assigned_to.username,
                    "email": ticket.assigned_to.email,
                    "display_name": ticket.assigned_to.display_name,
                    "role": ticket.assigned_to.role,
                    "status": ticket.assigned_to.status
                }
            
            ticket_response = TicketResponse(
                id=ticket.id,
                title=ticket.title,
                description=ticket.description,
                status=ticket.status,
                priority=ticket.priority,
                category=ticket.category,
                source=ticket.source,
                created_by_id=ticket.created_by_id,
                assigned_to_id=ticket.assigned_to_id,
                created_at=ticket.created_at,
                updated_at=ticket.updated_at,
                resolved_at=ticket.resolved_at,
                closed_at=ticket.closed_at,
                reply_count=ticket.reply_count,
                first_response_time=ticket.first_response_time,
                resolution_time=ticket.resolution_time,
                tags=ticket.tags,
                custom_fields=ticket.custom_fields,
                created_by=created_by_dict,
                assigned_to=assigned_to_dict
            )
            ticket_responses.append(ticket_response)
        
        return ticket_responses
    except Exception as e:
        logger.error(f"获取工单列表失败: {e}")
        raise HTTPException(
            status_code=http_status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="获取工单列表失败"
        )


@router.get("/{ticket_id}", response_model=None)
async def get_ticket(
    ticket_id: uuid.UUID,
    current_user: User = Depends(get_current_active_user_dep),
    db: Session = Depends(get_db)
) -> TicketResponse:
    """获取单个工单详情"""
    try:
        ticket = TicketService.get_ticket(db, ticket_id, current_user)
        
        # 手动处理User对象到字典的转换
        created_by_dict = None
        if ticket.created_by:
            created_by_dict = {
                "id": ticket.created_by.id,
                "username": ticket.created_by.username,
                "email": ticket.created_by.email,
                "display_name": ticket.created_by.display_name,
                "role": ticket.created_by.role,
                "status": ticket.created_by.status
            }
        
        assigned_to_dict = None
        if ticket.assigned_to:
            assigned_to_dict = {
                "id": ticket.assigned_to.id,
                "username": ticket.assigned_to.username,
                "email": ticket.assigned_to.email,
                "display_name": ticket.assigned_to.display_name,
                "role": ticket.assigned_to.role,
                "status": ticket.assigned_to.status
            }
        
        ticket_response = TicketResponse(
            id=ticket.id,
            title=ticket.title,
            description=ticket.description,
            status=ticket.status,
            priority=ticket.priority,
            category=ticket.category,
            source=ticket.source,
            created_by_id=ticket.created_by_id,
            assigned_to_id=ticket.assigned_to_id,
            created_at=ticket.created_at,
            updated_at=ticket.updated_at,
            resolved_at=ticket.resolved_at,
            closed_at=ticket.closed_at,
            reply_count=ticket.reply_count,
            first_response_time=ticket.first_response_time,
            resolution_time=ticket.resolution_time,
            tags=ticket.tags,
            custom_fields=ticket.custom_fields,
            created_by=created_by_dict,
            assigned_to=assigned_to_dict
        )
        
        return ticket_response
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"获取工单详情失败: {e}")
        raise HTTPException(
            status_code=http_status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="获取工单详情失败"
        )


@router.put("/{ticket_id}", response_model=None)
async def update_ticket(
    ticket_id: uuid.UUID,
    update_data: TicketUpdate,
    current_user: User = Depends(require_agent_or_admin),
    db: Session = Depends(get_db)
) -> TicketResponse:
    """更新工单"""
    try:
        ticket = TicketService.update_ticket(db, ticket_id, update_data, current_user)
        
        # 手动处理User对象到字典的转换
        created_by_dict = None
        if ticket.created_by:
            created_by_dict = {
                "id": ticket.created_by.id,
                "username": ticket.created_by.username,
                "email": ticket.created_by.email,
                "display_name": ticket.created_by.display_name,
                "role": ticket.created_by.role,
                "status": ticket.created_by.status
            }
        
        assigned_to_dict = None
        if ticket.assigned_to:
            assigned_to_dict = {
                "id": ticket.assigned_to.id,
                "username": ticket.assigned_to.username,
                "email": ticket.assigned_to.email,
                "display_name": ticket.assigned_to.display_name,
                "role": ticket.assigned_to.role,
                "status": ticket.assigned_to.status
            }
        
        ticket_response = TicketResponse(
            id=ticket.id,
            title=ticket.title,
            description=ticket.description,
            status=ticket.status,
            priority=ticket.priority,
            category=ticket.category,
            source=ticket.source,
            created_by_id=ticket.created_by_id,
            assigned_to_id=ticket.assigned_to_id,
            created_at=ticket.created_at,
            updated_at=ticket.updated_at,
            resolved_at=ticket.resolved_at,
            closed_at=ticket.closed_at,
            reply_count=ticket.reply_count,
            first_response_time=ticket.first_response_time,
            resolution_time=ticket.resolution_time,
            tags=ticket.tags,
            custom_fields=ticket.custom_fields,
            created_by=created_by_dict,
            assigned_to=assigned_to_dict
        )
        
        return ticket_response
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"更新工单失败: {e}")
        raise HTTPException(
            status_code=http_status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="更新工单失败"
        )


@router.post("/{ticket_id}/replies", response_model=None)
async def add_reply(
    ticket_id: uuid.UUID,
    reply_data: TicketReplyCreate,
    current_user: User = Depends(get_current_active_user_dep),
    db: Session = Depends(get_db)
) -> TicketReplyResponse:
    """添加工单回复"""
    try:
        reply = TicketService.add_reply(db, ticket_id, reply_data, current_user)
        return TicketReplyResponse.from_orm(reply)
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"添加工单回复失败: {e}")
        raise HTTPException(
            status_code=http_status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="添加工单回复失败"
        )


@router.get("/{ticket_id}/replies", response_model=None)
async def get_replies(
    ticket_id: uuid.UUID,
    include_internal: bool = Query(False),
    current_user: User = Depends(get_current_active_user_dep),
    db: Session = Depends(get_db)
) -> List[TicketReplyResponse]:
    """获取工单回复列表"""
    try:
        replies = TicketService.get_replies(db, ticket_id, current_user, include_internal)
        return [TicketReplyResponse.from_orm(reply) for reply in replies]
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"获取工单回复列表失败: {e}")
        raise HTTPException(
            status_code=http_status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="获取工单回复列表失败"
        )


@router.get("/{ticket_id}/stats", response_model=None)
async def get_ticket_stats(
    current_user: User = Depends(require_agent_or_admin),
    db: Session = Depends(get_db)
) -> TicketStats:
    """获取工单统计信息"""
    try:
        stats = TicketService.get_stats(db, current_user)
        return stats
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"获取工单统计信息失败: {e}")
        raise HTTPException(
            status_code=http_status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="获取工单统计信息失败"
        )


@router.post("/{ticket_id}/assign/{user_id}")
async def assign_ticket(
    ticket_id: uuid.UUID,
    user_id: uuid.UUID,
    current_user: User = Depends(require_agent_or_admin),
    db: Session = Depends(get_db)
) -> dict:
    """手动分配工单给指定用户"""
    try:
        update_data = TicketUpdate(assigned_to_id=user_id)
        ticket = TicketService.update_ticket(db, ticket_id, update_data, current_user)
        return {"message": "工单分配成功", "ticket": TicketResponse.from_orm(ticket)}
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"分配工单失败: {e}")
        raise HTTPException(
            status_code=http_status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="分配工单失败"
        )


@router.post("/{ticket_id}/close")
async def close_ticket(
    ticket_id: uuid.UUID,
    current_user: User = Depends(require_agent_or_admin),
    db: Session = Depends(get_db)
) -> dict:
    """关闭工单"""
    try:
        update_data = TicketUpdate(status="closed")
        ticket = TicketService.update_ticket(db, ticket_id, update_data, current_user)
        return {"message": "工单已关闭", "ticket": TicketResponse.from_orm(ticket)}
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"关闭工单失败: {e}")
        raise HTTPException(
            status_code=http_status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="关闭工单失败"
        )


@router.post("/{ticket_id}/reopen")
async def reopen_ticket(
    ticket_id: uuid.UUID,
    current_user: User = Depends(get_current_active_user_dep),
    db: Session = Depends(get_db)
) -> dict:
    """重新打开工单"""
    try:
        update_data = TicketUpdate(status="reopened")
        ticket = TicketService.update_ticket(db, ticket_id, update_data, current_user)
        return {"message": "工单已重新打开", "ticket": TicketResponse.from_orm(ticket)}
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"重新打开工单失败: {e}")
        raise HTTPException(
            status_code=http_status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="重新打开工单失败"
        )


@router.get("/search")
async def search_tickets(
    q: str = Query(..., min_length=2, description="搜索关键词"),
    current_user: User = Depends(get_current_active_user_dep),
    db: Session = Depends(get_db)
) -> List[TicketResponse]:
    """搜索工单"""
    try:
        filters = TicketFilter(search=q)
        tickets = TicketService.get_tickets(db, current_user, filters)
        return [TicketResponse.from_orm(ticket) for ticket in tickets]
    except Exception as e:
        logger.error(f"搜索工单失败: {e}")
        raise HTTPException(
            status_code=http_status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="搜索工单失败"
        )
